package nautilus.placetaker;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import android.widget.Toast;
import nautilus.placetaker.dao.AccountDAO;
import nautilus.placetaker.dao.DataFileUtils;
import nautilus.placetaker.dto.Place;
import nautilus.utility.ImageUtility;

public class MainActivity extends FragmentActivity implements OnClickListener {
	
	public static final int REQUEST_TAKE_PICTURE = 1;
	public static final String PICTURE_STORE = Environment.getExternalStorageDirectory()+ "/placetaker/";
	protected static final int R_CODE_SETTING_LOCATION = 100;
	private File[] images = new File[4];
	private EditText edtName, edtAddress;
	private Spinner spinnerCategory;
	private ImageView imgCurrentPic;
	private ImageView[] imageViews = new ImageView[4];
	private Button btnNewPlace, btnSave, btnRecordAudio;
	private CheckBox chkVerified;
	EditText edtLat, edtLon;
	Location _location;
	private int imgCount = 0;
	LocationManager lm;
	private MediaRecorder mRecorder = null;
	Place thisPlace = null;
	
	String[] categories = {"Park/Zooz","Food", "Entertainment", 
			"Coffee", "Restauran", "Shopping", "Education", "Primary School", 
			"High School", "Colleges","University",
			"Market", "Super Market", "Mobike Service",
			"IT Company", "Transport Station",
			"Fuel/Petrol Station", "Hotel", "Home"};
	
	boolean mStartRecording = true;
	
	boolean waitingForLocationToSave = false;
	DisplayMetrics displaymetrics = new DisplayMetrics();
    
    private void onRecord(boolean start) {
        if (start) {
            startRecording();
        } else {
            stopRecording();
        }
    }
    
    String mFileName;
    private void startRecording() {
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        SimpleDateFormat format = new SimpleDateFormat("ddMMyyyyhhmmss");
        File dir = new File(PICTURE_STORE);
		if (!dir.exists()) {
			dir.mkdirs();
		}
        mFileName = dir.getAbsolutePath() + "/aud" +format.format(new Date()) + ".3gp";
        mRecorder.setOutputFile(mFileName);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

        try {
            mRecorder.prepare();
        } catch (IOException e) {
            android.util.Log.e("MainActivity", "prepare() failed");
        }

        mRecorder.start();
    }

    private void stopRecording() {
        mRecorder.stop();
        mRecorder.release();
        mRecorder = null;
    }
	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		btnNewPlace = (Button) findViewById(R.id.btn_new_place);
		btnSave = (Button) findViewById(R.id.btn_save_place);
		btnRecordAudio = (Button) findViewById(R.id.btn_record_audio);
		
		btnNewPlace.setOnClickListener(this);
		btnSave.setOnClickListener(this);
		btnRecordAudio.setOnClickListener(this);
		
		edtName = (EditText)findViewById(R.id.edt_name);
		edtAddress = (EditText)findViewById(R.id.edt_address);
		edtLat = (EditText)findViewById(R.id.edt_Lat);
		edtLon = (EditText)findViewById(R.id.edt_Longitude);
		
		spinnerCategory = (Spinner) findViewById(R.id.spinner_category);
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
				android.R.layout.simple_spinner_item, categories);
		spinnerCategory.setAdapter(adapter);
		
		imgCurrentPic = (ImageView) findViewById(R.id.img_currentPic);
		imageViews[0] = (ImageView) findViewById(R.id.img1);
		imageViews[1] = (ImageView) findViewById(R.id.img2);
		imageViews[2] = (ImageView) findViewById(R.id.img3);
		imageViews[3] = (ImageView) findViewById(R.id.img4);
		
		chkVerified = (CheckBox) findViewById(R.id.chkVerify);
		
		imageViews[0].setOnClickListener(this);
		imageViews[1].setOnClickListener(this);
		imageViews[2].setOnClickListener(this);
		imageViews[3].setOnClickListener(this);
		
		getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
		if(savedInstanceState != null){
			imgCount = savedInstanceState.getInt("imgCount");
			if(imgCount==4)
				imgCount--;
			float w = displaymetrics.widthPixels * 0.7f;
			for(int i=0; i<imgCount+1; i++){
				images[i] = (File)savedInstanceState.getSerializable("images"+i);
				if(i<imgCount){
					Bitmap bm = ImageUtility.decodeSampledBitmapFromUri(images[i].getAbsolutePath(), (int)w, (int)w);
					imageViews[i].setImageBitmap(bm);
				}
			}
		}
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		boolean enable_gps;
		boolean enable_network;
		
//		//Enable Location service
//		String providers = android.provider.Settings.Secure.getString(this.getContentResolver(),
//						android.provider.Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
//		if(providers.isEmpty()){
//			FragmentManager fm = getSupportFragmentManager();
//			EnableGPSDlgFragment gpsDlg = new EnableGPSDlgFragment();
//			gpsDlg.show(fm, "enable_location_service");
//		}
				
		if(lm == null) {
			lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
			enable_gps = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
			enable_network = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
			
			if(!enable_gps && !enable_network) {
				Builder dialog = new AlertDialog.Builder(this);
				dialog.setMessage("Location Service is disabled. Do you want to enable?");
				dialog.setPositiveButton("Setting", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						startActivityForResult(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), 
								R_CODE_SETTING_LOCATION);
					}
				});
				
				dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){

					@Override
					public void onClick(DialogInterface dialog, int which) {
						
					}
					
				});
				dialog.show();
			}
			
			lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
			Criteria cri = new Criteria();
			cri.setPowerRequirement(Criteria.POWER_LOW);
			cri.setAccuracy(Criteria.ACCURACY_FINE);
			String bestProvider = lm.getBestProvider(cri, false);
			lm.requestLocationUpdates(bestProvider, 7000, 5, locationListener);
			
//			switch(NautilusApplication.instance.getLocationProvider()) {
//				case 0:
//					
//					break;
//				case 1:
//					lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 7000, 5, locationListener);
//					break;
//				default:
//					lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 7000, 5, locationListener);
//					lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 7000, 5, locationListener);
//					break;
//			}
		}
	}
	
	@Override
	public void onSaveInstanceState(Bundle outState){
		super.onSaveInstanceState(outState);
		for(int i=0; i<imgCount+1; i++)
			outState.putSerializable("images" + i, images[i]);
		outState.putInt("imgCount", imgCount);
		String strLat = edtLat.getText().toString();
		String strLongitude = edtLon.getText().toString();
		outState.putString("LATITUDE", strLat);
		outState.putString("LONGITUDE", strLongitude);
	}
	
	LocationListener locationListener = new LocationListener(){

		@Override
		public void onLocationChanged(Location location) {
			// TODO Auto-generated method stub
			edtLat.setText(location.getLatitude()+"");
			edtLon.setText(location.getLongitude()+"");
			
			if(waitingForLocationToSave){
				waitingForLocationToSave = false;
			}
		}

		@Override
		public void onProviderDisabled(String provider) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onProviderEnabled(String provider) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
			// TODO Auto-generated method stub
			
		}
		
	};
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	private void onTakePhotoClicked(){
		if(imgCount == 4)
			return;
		
		Intent intentTakePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		File dir = new File(PICTURE_STORE);
		if (!dir.exists()) {
			dir.mkdirs();
		}
		SimpleDateFormat format = new SimpleDateFormat("ddMMyyyyhhmmss");
		images[imgCount] = new File(dir.getAbsolutePath() +"/pic"+ format.format(new Date())+ ".jpg");
		intentTakePhoto.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(images[imgCount]));
		startActivityForResult(intentTakePhoto, REQUEST_TAKE_PICTURE);
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data){
		if( (resultCode == Activity.RESULT_OK) && (requestCode == REQUEST_TAKE_PICTURE )){			
			float w = displaymetrics.widthPixels * 0.7f;
			android.util.Log.i("MainActivity", "resultCode: "+ 
			resultCode +"( need: " + Activity.RESULT_OK +"); RequestCode: " 
					+ requestCode + "; imageCount: " + imgCount + "; image: " + images[imgCount]);
		    Bitmap tempBmp = ImageUtility.decodeSampledBitmapFromUri(images[imgCount].getAbsolutePath(), (int)w, (int)w);
		    imageViews[imgCount].setImageBitmap(tempBmp);
		    imageViews[imgCount].postInvalidate();
		    imgCurrentPic.setImageBitmap(tempBmp);
		    imgCurrentPic.postInvalidate();
		    imgCount++;
		}
	}
	
	private void onSaveBtnClicked(){
		if(thisPlace==null)
			thisPlace = new Place();
		String name = edtName.getText().toString();
		String address = edtAddress.getText().toString();
		String categoryName = (String)spinnerCategory.getSelectedItem();
		int categoryId = spinnerCategory.getSelectedItemPosition();
		String lat = edtLat.getText().toString();
		String lon = edtLon.getText().toString();
		
		SimpleDateFormat format = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss");
		thisPlace.setLastUpdate(format.format(new Date()));
		
		thisPlace.setName(name);
		thisPlace.setAddress(address);
		thisPlace.setCategoryId(categoryId);
		thisPlace.setCategoryName(categoryName);
		thisPlace.setChecked(chkVerified.isChecked());
		
		for(int i=0; i<imgCount; i++){
			thisPlace.addImage(images[i].getName());
		}
		thisPlace.setLatitude(Double.parseDouble(lat));
		thisPlace.setLongitude(Double.parseDouble(lon));
		
		if(lat.length() <=0 || lon.length()<=0){
			waitingForLocationToSave = true;
			return;
		}
		
		AsyncTask<Void, Void, Void> saveTask = new AsyncTask<Void, Void, Void>(){

			@Override
			protected Void doInBackground(Void... params) {
				AccountDAO dao = new AccountDAO(MainActivity.this);
				if(thisPlace.getId() <= 0)
					dao.addPlace(thisPlace);
				else
					dao.updatePlace(thisPlace);
				return null;
			}
			
			protected void onPostExecute(Void result){
				super.onPostExecute(result);
				Toast.makeText(MainActivity.this, "Place has been saved", Toast.LENGTH_LONG).show();
				waitingForLocationToSave = false;
			}
		};
		saveTask.execute();
	}

	@Override
	public void onClick(View v) {
		switch(v.getId()){
			case R.id.img1:
				if(images[0]!=null){
					float w = displaymetrics.widthPixels * 0.7f;
					Bitmap tempBmp = ImageUtility.decodeSampledBitmapFromUri(images[0].getAbsolutePath(), (int)w, (int)w);
					imgCurrentPic.setImageBitmap(tempBmp);
				    imgCurrentPic.postInvalidate();
				    break;
				}
				onTakePhotoClicked();
				break;
			case R.id.img2:
				if(images[1]!=null){
					float w = displaymetrics.widthPixels * 0.7f;
					Bitmap tempBmp = ImageUtility.decodeSampledBitmapFromUri(images[1].getAbsolutePath(), (int)w, (int)w);
					imgCurrentPic.setImageBitmap(tempBmp);
				    imgCurrentPic.postInvalidate();
				    break;
				}
				onTakePhotoClicked();
				break;
			case R.id.img3:
				if(images[2]!=null){
					float w = displaymetrics.widthPixels * 0.7f;
					Bitmap tempBmp = ImageUtility.decodeSampledBitmapFromUri(images[2].getAbsolutePath(), (int)w, (int)w);
					imgCurrentPic.setImageBitmap(tempBmp);
				    imgCurrentPic.postInvalidate();
				    break;
				}
				onTakePhotoClicked();
				break;
			case R.id.img4:
				if(images[3]!=null){
					float w = displaymetrics.widthPixels * 0.7f;
					Bitmap tempBmp = ImageUtility.decodeSampledBitmapFromUri(images[3].getAbsolutePath(), (int)w, (int)w);
					imgCurrentPic.setImageBitmap(tempBmp);
				    imgCurrentPic.postInvalidate();
				    break;
				}
				onTakePhotoClicked();
				break;
				
			case R.id.btn_record_audio:
				onRecord(mStartRecording);
	            if (mStartRecording) {
	                btnRecordAudio.setText("Stop recording");
	            } else {
	                btnRecordAudio.setText("Start recording");
	            }
	            mStartRecording = !mStartRecording;
				break;
				
			case R.id.btn_new_place:
				thisPlace = null;
				imgCurrentPic.setImageDrawable(getResources().getDrawable(R.drawable.default_picture_tran));
				
				imageViews[0].setImageDrawable(getResources().getDrawable(R.drawable.album_camera_capture));
				imageViews[1].setImageDrawable(getResources().getDrawable(R.drawable.album_camera_capture));
				imageViews[2].setImageDrawable(getResources().getDrawable(R.drawable.album_camera_capture));
				imageViews[3].setImageDrawable(getResources().getDrawable(R.drawable.album_camera_capture));
				break;
				
			case R.id.btn_save_place:
				onSaveBtnClicked();
				break;
		}
		
	}
	
	@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.action_settings:
        	break;
        case R.id.action_backup:
            // Ensure this device is discoverable by others
        	AsyncTask<Void, Void, String> backupTask = new AsyncTask<Void, Void, String>(){

				@Override
				protected String doInBackground(Void... params) {
					File dir = new File(PICTURE_STORE);
		    		if (!dir.exists()) {
		    			dir.mkdirs();
		    		}
		    		SimpleDateFormat format = new SimpleDateFormat("ddMMyyyyhhmmss");
		    		File csvFile = new File(dir.getAbsolutePath() +"/data"+ format.format(new Date())+ ".csv");
		    		AccountDAO dao = new AccountDAO(MainActivity.this);
		    		ArrayList<Place> places = dao.getAllPlaces();
		    		try {
						DataFileUtils.exportPlacesToCSV(places, csvFile.getAbsolutePath());
						return "Backup successfully";
					} catch (IOException e) {
						// TODO Auto-generated catch block
						return e.getMessage();
					}
				}
				
				protected void onPostExecute(String result){
					super.onPostExecute(result);
					Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
				}
        	};
        	backupTask.execute();
            return true;
            
        	case R.id.action_list_places:
        		Intent intent = new Intent(this, ListPlaces.class);
        		startActivity(intent);
        	return true;
        }
        return false;
    }
}

class EnableGPSDlgFragment extends DialogFragment {
	
	private Button btnTurnOn, btnCancel;
	private TextView tvMessage;
	private RelativeLayout rlayout;
	
	public EnableGPSDlgFragment(){
		
	}
	
	private void initComponent(){
		rlayout = new RelativeLayout(getActivity());
		rlayout.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,
				LayoutParams.MATCH_PARENT));
		btnTurnOn = new Button(getActivity());
		btnTurnOn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
			}
		});
		btnTurnOn.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT));
		rlayout.addView(btnTurnOn);
	}
	
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
		
		if(container == null)
			return null;
		
		initComponent();
		container.addView(rlayout);
		return rlayout;
	}
}
